package com.linkage.educloud.ah.data;

import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.util.Log;

import com.linkage.educloud.ah.Constants;
import com.yanzhenjie.nohttp.Logger;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;


/**
 * A Provider for IM
 *
 * @author zhouzhen
 */
public class WsProvider extends ContentProvider {

    private static final String TAG = "anhui_edu";
    private static final boolean DBG = true;

    private static final String DATABASE_NAME = "anhui_edu.db";
    private static final int DATABASE_VERSION = 5;

    private static final int MATCH_ACCOUNTS = 10;
    private static final int MATCH_ACCOUNT_BY_ID = 11;
    private static final int MATCH_ACCOUNT_DEFAULT_USER = 12;

    private static final int MATCH_CHILD = 20;
    private static final int MATCH_CHILD_USER = 21;

    private static final int MATCH_MESSAGES = 30;
    private static final int MATCH_MESSAGES_BY_BUDDY_ID = 31;
    private static final int MATCH_MESSAGES_BY_GROUP_ID = 32;
    private static final int MATCH_MESSAGES_BY_ID = 33;

    private static final int MATCH_THREADS = 40;
    private static final int MATCH_THREADS_BY_ID = 41;
    private static final int MATCH_THREAD_BY_BUDDY_ID = 42;

    private static final int MATCH_CONTACT = 50;
    private static final int MATCH_CONTACT_ID = 51;
    private static final int MATCH_GROUP = 52;
    private static final int MATCH_GROUP_BY_ID = 53;

    protected final UriMatcher mUrlMatcher = new UriMatcher(UriMatcher.NO_MATCH);

    private DatabaseHelper mOpenHelper;
    private String mDatabaseName;
    private int mDatabaseVersion;

    private class DatabaseHelper extends SQLiteOpenHelper {

        public DatabaseHelper(Context context) {
            super(context, mDatabaseName, null, mDatabaseVersion);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL(Ws.AccountTable.CREATE_TABLE_SQL);
            db.execSQL(Ws.ChildTable.CREATE_TABLE_SQL);
            db.execSQL(Ws.ThreadTable.CREATE_TABLE_SQL);
            db.execSQL(Ws.MessageTable.CREATE_TABLE_SQL);
            db.execSQL(Ws.GroupTable.CREATE_TABLE_SQL);
            db.execSQL(Ws.ContactTable.CREATE_TABLE_SQL);
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            destroyOldTables(db);
            onCreate(db);
        }

        private void destroyOldTables(SQLiteDatabase db) {
            db.execSQL("DROP TABLE IF EXISTS " + Ws.AccountTable.TABLE_NAME);
            db.execSQL("DROP TABLE IF EXISTS " + Ws.ChildTable.TABLE_NAME);
            db.execSQL("DROP TABLE IF EXISTS " + Ws.ThreadTable.TABLE_NAME);
            db.execSQL("DROP TABLE IF EXISTS " + Ws.MessageTable.TABLE_NAME);
            db.execSQL("DROP TABLE IF EXISTS " + Ws.GroupTable.TABLE_NAME);
            db.execSQL("DROP TABLE IF EXISTS " + Ws.ContactTable.TABLE_NAME);
        }

    }

    public WsProvider() {
        this(DATABASE_NAME, DATABASE_VERSION);
        setupImUrlMatchers(Ws.AUTHORITY);
    }

    protected WsProvider(String databaseName, int databaseVersion) {
        this.mDatabaseName = databaseName;
        this.mDatabaseVersion = databaseVersion;
    }

    private void setupImUrlMatchers(String authority) {
        mUrlMatcher.addURI(authority, Ws.AccountTable.PATH, MATCH_ACCOUNTS);
        mUrlMatcher.addURI(authority, Ws.AccountTable.PATH + "/#", MATCH_ACCOUNT_BY_ID);
        mUrlMatcher.addURI(authority, Ws.AccountTable.PATH_DEFAULT_USER + "/#", MATCH_ACCOUNT_DEFAULT_USER);
        mUrlMatcher.addURI(authority, Ws.ChildTable.PATH, MATCH_CHILD);
        mUrlMatcher.addURI(authority, Ws.ChildTable.PATH + "/#", MATCH_CHILD_USER);

        mUrlMatcher.addURI(authority, "threads", MATCH_THREADS);
        mUrlMatcher.addURI(authority, "threads/#", MATCH_THREADS_BY_ID);
        mUrlMatcher.addURI(authority, "threadByBuddyId/#",
                MATCH_THREAD_BY_BUDDY_ID);

        mUrlMatcher.addURI(authority, "messages", MATCH_MESSAGES);
        mUrlMatcher.addURI(authority, "messagesByBuddyId/#",
                MATCH_MESSAGES_BY_BUDDY_ID);
        mUrlMatcher.addURI(authority, "messagesByGroupId/#",
                MATCH_MESSAGES_BY_GROUP_ID);
        mUrlMatcher.addURI(authority, "messages/#", MATCH_MESSAGES_BY_ID);

        mUrlMatcher.addURI(authority, Ws.GroupTable.PATH, MATCH_GROUP);
        mUrlMatcher.addURI(authority, Ws.GroupTable.PATH + "/#", MATCH_GROUP_BY_ID);
        mUrlMatcher.addURI(authority, Ws.ContactTable.PATH, MATCH_CONTACT);
        mUrlMatcher.addURI(authority, Ws.ContactTable.PATH + "/#", MATCH_CONTACT_ID);
    }

    @Override
    public String getType(Uri uri) {
        int match = mUrlMatcher.match(uri);
        switch (match) {
            case MATCH_ACCOUNTS:
                return Ws.AccountTable.CONTENT_TYPE;
            case MATCH_ACCOUNT_BY_ID:
            case MATCH_ACCOUNT_DEFAULT_USER:
                return Ws.AccountTable.CONTENT_ITEM_TYPE;
            case MATCH_CHILD:
                return Ws.ChildTable.CONTENT_TYPE;
            case MATCH_CHILD_USER:
                return Ws.ChildTable.CONTENT_ITEM_TYPE;
            case MATCH_THREADS:
                return Ws.ThreadTable.CONTENT_TYPE;
            case MATCH_THREADS_BY_ID:
                return Ws.ThreadTable.CONTENT_ITEM_TYPE;
            case MATCH_MESSAGES:
                return Ws.MessageTable.CONTENT_TYPE;
            case MATCH_MESSAGES_BY_BUDDY_ID:
                return Ws.MessageTable.CONTENT_ITEM_TYPE;
            case MATCH_MESSAGES_BY_GROUP_ID:
                return Ws.MessageTable.CONTENT_ITEM_TYPE;
            case MATCH_GROUP:
                return Ws.GroupTable.CONTENT_TYPE;
            case MATCH_GROUP_BY_ID:
                return Ws.GroupTable.CONTENT_ITEM_TYPE;
            case MATCH_CONTACT_ID:
                return Ws.ContactTable.CONTENT_ITEM_TYPE;
            case MATCH_CONTACT:
                return Ws.ContactTable.CONTENT_TYPE;
            default:
                throw new IllegalArgumentException("Unknow URL");
        }
    }

    @Override
    public boolean onCreate() {
        mOpenHelper = new DatabaseHelper(getContext());
        return true;
    }

    @Override
    public Cursor query(final Uri uri, final String[] projection,
                        final String selection, final String[] selectionArgs,
                        final String sortOrder) {
        if (DBG) {
            log("url " + uri.toString());
        }
        return queryInternal(uri, projection, selection, selectionArgs,
                sortOrder);
    }

    @Override
    public Uri insert(final Uri uri, final ContentValues values) {
        if (DBG) {
            log("url " + uri.toString());
        }
        Uri result;
        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
        db.beginTransaction();
        try {
            result = insertInternal(uri, values);
            db.setTransactionSuccessful();
        } finally {
            db.endTransaction();
        }

        if (result != null) {
            getContext().getContentResolver().notifyChange(uri, null, false);
        }
        return result;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        if (DBG) {
            log("url " + uri.toString());
        }
        int result;
        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
        db.beginTransaction();
        try {
            result = deleteInternal(uri, selection, selectionArgs);
            db.setTransactionSuccessful();
        } finally {
            db.endTransaction();
        }

        if (result > 0) {
            getContext().getContentResolver().notifyChange(uri, null, false);
        }

        return result;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection,
                      String[] selectionArgs) {
        int result = 0;
        SQLiteDatabase db = mOpenHelper.getWritableDatabase();

        db.beginTransaction();
        try {
            result = updateInternal(uri, values, selection, selectionArgs);
            db.setTransactionSuccessful();
        } finally {
            db.endTransaction();
        }

        return result;
    }

    private int updateInternal(Uri url, ContentValues values, String selection,
                               String[] selectionArgs) {
        String tableToChanged = null;
        String buddyId = "";
        long userStutas;
        long msgId = -1;

        boolean notifyThreadsContentUri = false;
        boolean notifyMessagesContentUri = false;
        StringBuilder whereClause = new StringBuilder();
        if (selection != null) {
            whereClause.append(selection);
        }

        int match = mUrlMatcher.match(url);
        SQLiteDatabase db = mOpenHelper.getWritableDatabase();

        switch (match) {
            case MATCH_ACCOUNT_BY_ID:
                try {
                    Long userId = Long.parseLong(url.getPathSegments().get(1));
                    appendWhere(whereClause, Ws.AccountTable.USER_ID, "=", userId);
                } catch (NumberFormatException e) {
                    throw new IllegalArgumentException();
                }
            case MATCH_ACCOUNTS:
                tableToChanged = Ws.AccountTable.TABLE_NAME;
                break;
            case MATCH_CHILD:
                tableToChanged = Ws.ChildTable.TABLE_NAME;
                break;
            case MATCH_THREADS:
                tableToChanged = Ws.ThreadTable.TABLE_NAME;
                notifyThreadsContentUri = true;
                break;
            case MATCH_MESSAGES_BY_BUDDY_ID:
                tableToChanged = Ws.ThreadTable.TABLE_NAME;
                buddyId = url.getPathSegments().get(1);
                appendWhere(whereClause, Ws.ThreadTable.BUDDY_ID, "=", buddyId);
                notifyThreadsContentUri = true;
                break;
            case MATCH_MESSAGES:
                tableToChanged = Ws.MessageTable.TABLE_NAME;
                notifyMessagesContentUri = true;
                break;
            case MATCH_MESSAGES_BY_ID:
                tableToChanged = Ws.MessageTable.TABLE_NAME;
                try {
                    msgId = Long.parseLong(url.getPathSegments().get(1));
                } catch (NumberFormatException e) {
                    throw new IllegalArgumentException();
                }

                appendWhere(whereClause, Ws.MessageTable._ID, "=", msgId);
                notifyMessagesContentUri = true;
                break;
            case MATCH_CONTACT:
                tableToChanged = Ws.ContactTable.TABLE_NAME;
                break;
            case MATCH_GROUP:
                tableToChanged = Ws.GroupTable.TABLE_NAME;
                break;
            default:
                throw new IllegalArgumentException("can't update the url" + url);
        }

        int count = db.update(tableToChanged, values, whereClause.toString(),
                selectionArgs);
        if (count > 0) {
            ContentResolver cr = getContext().getContentResolver();
            if (notifyThreadsContentUri) {
                cr.notifyChange(Ws.ThreadTable.CONTENT_URI, null, false);
            }

            if (notifyMessagesContentUri) {
                cr.notifyChange(Ws.MessageTable.CONTENT_URI_MESSAGES_BY_BUDDY_ID,
                        null, false);
            }
        }
        return count;
    }

    public Uri insertInternal(Uri uri, ContentValues values) {
        Uri resultUri = null;
        long rowId = 0;
        if (DBG) {
            log("url " + uri.toString());
        }
        SQLiteDatabase db = mOpenHelper.getWritableDatabase();

        int match = mUrlMatcher.match(uri);
        String accountname;
        String buddyid;
        int chattype;
        Cursor c;
        switch (match) {
            case MATCH_ACCOUNT_BY_ID:
                appendValuesFromUrl(values, uri, Ws.AccountTable.USER_ID);//貌似有问题，不用这种方式插入
                rowId = db.update(Ws.AccountTable.TABLE_NAME, values, null, null);
                if (rowId > 0) {
                    resultUri = Uri.parse(Ws.AccountTable.CONTENT_URI + "/" + rowId);
                }
                break;
            case MATCH_ACCOUNTS:
                rowId = db.insert(Ws.AccountTable.TABLE_NAME, null, values);
                if (rowId > 0) {
                    resultUri = Uri.parse(Ws.AccountTable.CONTENT_URI + "/" + rowId);
                }
                break;
            case MATCH_CHILD:
                rowId = db.insert(Ws.ChildTable.TABLE_NAME, null, values);
                if (rowId > 0) {
                    resultUri = Uri.parse(Ws.AccountTable.CONTENT_URI + "/" + rowId);
                }
                break;
            case MATCH_THREADS:
                accountname = values.getAsString(Ws.ThreadTable.ACCOUNT_NAME);
                buddyid = values.getAsString(Ws.ThreadTable.BUDDY_ID);
                chattype = values.getAsInteger(Ws.ThreadTable.CHAT_TYPE);
                c = db.query(
                        Ws.ThreadTable.TABLE_NAME,
                        null,
                        Ws.ThreadTable.ACCOUNT_NAME + "=? and " + Ws.ThreadTable.BUDDY_ID
                                + "=? and " + Ws.ThreadTable.CHAT_TYPE + "=?",
                        //new String[] { accountname, String.valueOf(buddyid),
                        new String[]{accountname, buddyid,
                                String.valueOf(chattype)},
                        null, null, null);

                if (c != null && c.getCount() > 0) {
                    c.moveToFirst();
                    long id = c.getLong(c.getColumnIndex(Ws.ThreadTable._ID));
                    int un_read_count = c.getInt(c
                            .getColumnIndex(Ws.ThreadTable.UNREAD_COUNT));
                    Logger.i("ws, un_read_count=" + un_read_count);

                    db.update(Ws.ThreadTable.TABLE_NAME,
//						createThreadContentValues(values, ++un_read_count),
                            createThreadContentValues(values, -1),
                            Ws.ThreadTable._ID + "=?",
                            new String[]{String.valueOf(id)});

                    Logger.d("threadtable, update data, id=" + id + ", buddyid=" + buddyid);

                } else {
                    db.insert(Ws.ThreadTable.TABLE_NAME, null,
//						createThreadContentValues(values, 1));
                            createThreadContentValues(values, -1));
                    Logger.d("threadtable,insert data, " + "buddyid=" + buddyid);
                }
                break;
            case MATCH_MESSAGES_BY_BUDDY_ID:
                break;
            case MATCH_MESSAGES_BY_GROUP_ID:
                break;
            case MATCH_MESSAGES:
                int type = values.getAsInteger(Ws.MessageTable.THREAD_TYPE);
                if (type != Constants.ThreadType.THREAD_IM_CLASS &&
                        type != Constants.ThreadType.THREAD_IM_SINGE &&
                        type != Constants.ThreadType.THREAD_TEMP_GROUP) {
                    accountname = values
                            .getAsString(Ws.MessageTable.ACCOUNT_NAME);
                    buddyid = values.getAsString(Ws.MessageTable.BUDDY_ID);
                    chattype = values.getAsInteger(Ws.MessageTable.CHAT_TYPE);
                    c = db
                            .query(Ws.ThreadTable.TABLE_NAME,
                                    null,
                                    Ws.ThreadTable.ACCOUNT_NAME + "=? and "
                                            + Ws.ThreadTable.BUDDY_ID + "=? and "
                                            + Ws.ThreadTable.CHAT_TYPE + "=? and "
                                            + Ws.ThreadTable.THREAD_TYPE + " =?",
                                    new String[]{accountname,
                                            buddyid,
                                            String.valueOf(chattype),
                                            String.valueOf(type)}, null, null,
                                    null);
                    if (c != null && c.getCount() > 0) {
//                        c.moveToFirst();
//                        long id = c.getLong(c.getColumnIndex(Ws.ThreadTable._ID));
//                        int un_read_count = c.getInt(c
//                                .getColumnIndex(Ws.ThreadTable.UNREAD_COUNT));
//                        db.update(Ws.ThreadTable.TABLE_NAME,
//                                createThreadContentValues(values, ++un_read_count),
//                                Ws.ThreadTable._ID + "=?",
//                                new String[]{String.valueOf(id)});

                    } else {
                        db.insert(Ws.ThreadTable.TABLE_NAME, null,
                                createThreadContentValues(values, 0));
                    }
                    ContentResolver cr = getContext().getContentResolver();
                    cr.notifyChange(Ws.ThreadTable.CONTENT_URI, null);
                    return null;
                }
                rowId = db.insert(Ws.MessageTable.TABLE_NAME, null, values);
                if (rowId > 0) {
                    resultUri = Uri.parse(Ws.MessageTable.CONTENT_URI + "/" + rowId);
                    accountname = values
                            .getAsString(Ws.MessageTable.ACCOUNT_NAME);
                     chattype = values.getAsInteger(Ws.MessageTable.CHAT_TYPE);
                     buddyid = values.getAsString(Ws.MessageTable.BUDDY_ID);
                    String msgtype = "(" + Ws.MessageType.TYPE_MSG_TEXT + ","
                            + Ws.MessageType.TYPE_MSG_PIC + ","
                            + Ws.MessageType.TYPE_MSG_AUDIO + ")";
                    c = db.query(Ws.ThreadTable.TABLE_NAME, null,
                            Ws.ThreadTable.ACCOUNT_NAME + "=? and "
                                    + Ws.ThreadTable.BUDDY_ID + "=? and "
                                    + Ws.ThreadTable.CHAT_TYPE + "=? and "
                                    + Ws.ThreadTable.MSG_TYPE + " in " + msgtype,
                            new String[]{accountname, buddyid,
                                    String.valueOf(chattype)}, null, null, null);

//                    values.put(ThreadTable.BUDDY_ID, buddyid);

                    Logger.d("---------------> find condition, accountname=" + accountname
                            + ", buddyid=" + buddyid + ", chattype=" + chattype + " type=" + values.getAsInteger(Ws.MessageTable.TYPE));

                    if (c != null && c.getCount() > 0) {
                        Logger.d("---------------> find old data, update, msgtype=" + values.getAsInteger(Ws.MessageTable.TYPE));
                        c.moveToFirst();
                        long id = c.getLong(c.getColumnIndex(Ws.ThreadTable._ID));
                        int un_read_count = c.getInt(c
                                .getColumnIndex(Ws.ThreadTable.UNREAD_COUNT));
                        db.update(Ws.ThreadTable.TABLE_NAME,
                                createThreadContentValues(values, ++un_read_count),
                                Ws.ThreadTable._ID + "=?",
                                new String[]{String.valueOf(id)});

                    } else {
                        db.insert(Ws.ThreadTable.TABLE_NAME, null,
                                createThreadContentValues(values, 1));
                        Logger.d("--------------->insert data, msgtype=" + values.getAsInteger(Ws.MessageTable.TYPE)
                                + " buddyid=" + buddyid);
                    }
                    // db.replace(TABLE_THREADS, ThreadTable.BUDDY_ID,
                    // createThreadContentValues(values));
                    getContext().getContentResolver().notifyChange(Ws.MessageTable.CONTENT_URI,null);
                }
                break;
            case MATCH_CONTACT:
                rowId = db.insert(Ws.ContactTable.TABLE_NAME, null, values);
                if (rowId > 0) {
                    resultUri = Uri.parse(Ws.ContactTable.CONTENT_URI + "/" + rowId);
                }
                break;
            case MATCH_GROUP:
                rowId = db.insert(Ws.GroupTable.TABLE_NAME, null, values);
                if (rowId > 0) {
                    resultUri = Uri.parse(Ws.GroupTable.CONTENT_URI + "/" + rowId);
                }
                break;
            default:
                throw new UnsupportedOperationException("Cannot insert into URL: "
                        + uri);
        }
        return resultUri;
    }

    public Cursor queryInternal(Uri uri, String[] projection, String selection,
                                String[] selectionArgs, String sortOrder) {
        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
        StringBuilder whereClause = new StringBuilder();
        if (selection != null) {
            whereClause.append(selection);
        }

        String groupBy = null;
        String limit = null;

        int match = mUrlMatcher.match(uri);
        if (DBG) {
            log("query url " + uri + ", match " + match + ", where "
                    + selection);
            if (selectionArgs != null) {
                for (String arg : selectionArgs) {
                    log(" selectionArg:" + arg);
                }
            }
        }

        switch (match) {
            case MATCH_ACCOUNT_BY_ID:
                appendWhere(whereClause, Ws.AccountTable.USER_ID, "=", uri
                        .getPathSegments().get(1));
            case MATCH_ACCOUNTS:
                qb.setTables(Ws.AccountTable.TABLE_NAME);
                break;
            case MATCH_ACCOUNT_DEFAULT_USER:
                appendWhere(whereClause, Ws.AccountTable.ISLOGINING, "=", uri
                        .getPathSegments().get(1));
                qb.setTables(Ws.AccountTable.TABLE_NAME);
                break;
            case MATCH_CHILD_USER:
                appendWhere(whereClause, Ws.ChildTable.PARENTID, "=", uri
                        .getPathSegments().get(1));
            case MATCH_CHILD:
                qb.setTables(Ws.ChildTable.TABLE_NAME);
                break;
            case MATCH_MESSAGES_BY_BUDDY_ID:
                appendWhere(whereClause, Ws.MessageTable.BUDDY_ID, "=", uri
                        .getPathSegments().get(1));
                break;
            case MATCH_MESSAGES:
                qb.setTables(Ws.MessageTable.TABLE_NAME);
                break;
            case MATCH_THREAD_BY_BUDDY_ID:
                appendWhere(whereClause, Ws.ThreadTable.BUDDY_ID, "=", uri
                        .getPathSegments().get(1));
                break;
            case MATCH_THREADS:
                qb.setTables(Ws.ThreadTable.TABLE_NAME);
                break;
            case MATCH_CONTACT:
                groupBy = Ws.ContactTable.REMOTEID;
                qb.setTables(Ws.ContactTable.TABLE_NAME);
                break;
            case MATCH_GROUP:
                qb.setTables(Ws.GroupTable.TABLE_NAME);
                break;
            default:
                throw new IllegalArgumentException("Unknow URL");
        }

        final SQLiteDatabase db = mOpenHelper.getReadableDatabase();
        Cursor c = null;

        try {
            c = qb.query(db, projection, whereClause.toString(), selectionArgs,
                    groupBy, null, sortOrder, limit);
            if (c != null) {
                c.setNotificationUri(getContext().getContentResolver(), uri);
            }
        } catch (Exception e) {
            Log.e("WsProvider", "query db caugh \n" + e);
        }

        return c;
    }

    private int deleteInternal(Uri url, String userWhere, String[] whereArgs) {
        String tableToChange;

        String idColumnName = null;
        String changedItemId = null;

        StringBuilder whereClause = new StringBuilder();
        if (userWhere != null) {
            whereClause.append(userWhere);
        }

        int match = mUrlMatcher.match(url);

        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();

        switch (match) {
            case MATCH_ACCOUNTS:
                tableToChange = Ws.AccountTable.TABLE_NAME;
                break;
            case MATCH_ACCOUNT_BY_ID:
                tableToChange = Ws.AccountTable.TABLE_NAME;
                changedItemId = url.getPathSegments().get(1);
                idColumnName = Ws.AccountTable.USER_ID;
                break;
            case MATCH_CHILD_USER:
                changedItemId = url.getPathSegments().get(1);
                idColumnName = Ws.ChildTable.PARENTID;
            case MATCH_CHILD:
                tableToChange = Ws.ChildTable.TABLE_NAME;
                break;
            case MATCH_THREADS:
                tableToChange = Ws.ThreadTable.TABLE_NAME;
                break;
            case MATCH_MESSAGES:
                tableToChange = Ws.MessageTable.TABLE_NAME;
                break;
            case MATCH_CONTACT:
                tableToChange = Ws.ContactTable.TABLE_NAME;
                break;
            case MATCH_CONTACT_ID:
                tableToChange = Ws.ContactTable.TABLE_NAME;
                changedItemId = url.getPathSegments().get(1);
                break;
            case MATCH_GROUP:
                tableToChange = Ws.GroupTable.TABLE_NAME;
                break;
            case MATCH_GROUP_BY_ID:
                tableToChange = Ws.GroupTable.TABLE_NAME;
                changedItemId = url.getPathSegments().get(1);
                break;
            default:
                throw new UnsupportedOperationException("Can't delete the url");
        }

        if (idColumnName == null) {
            idColumnName = "_id";
        }

        if (changedItemId != null) {
            appendWhere(whereClause, idColumnName, "=", changedItemId);
        }

        if (DBG)
            log("delete from " + url + " WHERE  " + whereClause);

        int count = db.delete(tableToChange, whereClause.toString(), whereArgs);

        return count;
    }

    private void appendValuesFromUrl(ContentValues values, Uri url,
                                     String... columns) {
        if (url.getPathSegments().size() <= columns.length) {
            throw new IllegalArgumentException("Not enough values in url");
        }
        for (int i = 0; i < columns.length; i++) {
            if (values.containsKey(columns[i])) {
                throw new UnsupportedOperationException(
                        "Cannot override the value for " + columns[i]);
            }
            values.put(columns[i],
                    decodeURLSegment(url.getPathSegments().get(i + 1)));
        }
    }
    private ContentValues createThreadContentValues(ContentValues values, int unread_count) {
        ContentValues cv = new ContentValues();

        int is_inbound = values.getAsInteger(Ws.MessageTable.IS_INBOUND);

        cv.put(Ws.ThreadTable.ACCOUNT_NAME,
                values.getAsString(Ws.MessageTable.ACCOUNT_NAME));
        cv.put(Ws.ThreadTable.BUDDY_ID, values.getAsString(Ws.MessageTable.BUDDY_ID));
        cv.put(Ws.ThreadTable.MSG_BODY, values.getAsString(Ws.MessageTable.BODY));
        cv.put(Ws.ThreadTable.MSG_IS_INBOUND,
                values.getAsInteger(Ws.MessageTable.IS_INBOUND));
        cv.put(Ws.ThreadTable.MSG_TYPE, values.getAsInteger(Ws.MessageTable.TYPE));
        cv.put(Ws.ThreadTable.MSG_SENT_TIME,
                values.getAsLong(Ws.MessageTable.SENT_TIME));
        cv.put(Ws.ThreadTable.MSG_RECEIVED_TIME,
                values.getAsLong(Ws.MessageTable.RECEIVED_TIME));
        cv.put(Ws.ThreadTable.CHAT_TYPE, values.getAsLong(Ws.MessageTable.CHAT_TYPE));
        cv.put(Ws.ThreadTable.THREAD_TYPE,
                values.getAsInteger(Ws.MessageTable.THREAD_TYPE));
//		cv.put(ThreadTable.USER_TYPE,
//				values.getAsInteger(MessageTable.USER_TYPE));

        if (values.containsKey(Ws.ThreadTable.ORG_NAME)) {
            Logger.d("---->has org_name key, is" + values.getAsString(Ws.ThreadTable.ORG_NAME));
            cv.put(Ws.ThreadTable.ORG_NAME, values.getAsString(Ws.ThreadTable.ORG_NAME));
        } else {
            Logger.e("---->do not has org_name key!!!");
            cv.put(Ws.ThreadTable.ORG_NAME, "");
        }
        boolean group = values.containsKey(Ws.MessageTable.CHAT_TYPE)
                && values.getAsInteger(Ws.MessageTable.CHAT_TYPE) == Constants.ChatType.CHAT_TYPE_GROUP;
        if (group) {
            cv.put(Ws.ThreadTable.USER_ID,
                    values.getAsLong(Ws.MessageTable.SENDER_ID));
        } else {
            cv.put(Ws.ThreadTable.USER_ID, 0);
        }
        // δ����
//		if (unread_count >= 0 && is_inbound == MessageType.INCOMING) {
//			cv.put(ThreadTable.UNREAD_COUNT, unread_count);
//		}

        if (unread_count >= 0) {
            if (is_inbound == Ws.MessageType.INCOMING) {
                cv.put(Ws.ThreadTable.UNREAD_COUNT, unread_count);
                Logger.d("chat---->createThreadContentValues, 1 unread_count=" + unread_count);
            } else {
                Logger.d("chat---->createThreadContentValues, no unread_count");
            }

        } else {
            cv.put(Ws.ThreadTable.UNREAD_COUNT, values.getAsInteger(Ws.ThreadTable.UNREAD_COUNT));
            Logger.d("chat---->createThreadContentValues, 2 unread_count=" + values.getAsInteger(Ws.ThreadTable.UNREAD_COUNT));
        }

        return cv;
    }
    private static String decodeURLSegment(String segment) {
        try {
            return URLDecoder.decode(segment, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            // impossible
            return segment;
        }
    }

    private static void appendWhere(StringBuilder where, String columnName,
                                    String condition, Object value) {
        if (where.length() > 0) {
            where.append(" AND ");
        }
        where.append(columnName).append(condition);
        if (value != null) {
            DatabaseUtils.appendValueToSql(where, value);
        }
    }

    static void log(String message) {
        Log.d(TAG, message);
    }
}